package pl.iachoo.ctl.tabory.ui.editors.compositions;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.apache.log4j.Logger;
import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.jface.layout.GridLayoutFactory;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.forms.widgets.Section;

import pl.iachoo.ctl.tabory.dao.data.vo.CompositionVO;
import pl.iachoo.ctl.tabory.dao.data.vo.VagonVO;
import pl.iachoo.ctl.tabory.ui.base.masterdetail.AbstractDetailSectionPart;
import pl.iachoo.ctl.tabory.ui.editors.vagons.VagonSelection;
import pl.iachoo.ctl.tabory.ui.editors.vagons.composites.VagonMasterSectionPart;
import pl.iachoo.ctl.tabory.ui.editors.vagons.composites.VagonMasterSectionPart.AvailableColumnsSL;
import pl.iachoo.ctl.tabory.ui.properties.Messages;
import pl.iachoo.ctl.tabory.ui.selection.ISelectionListener;

public class CompositionDetailSectionPart extends
		AbstractDetailSectionPart<CompositionSelection> {

	private final static Logger logger = Logger
			.getLogger(CompositionDetailSectionPart.class);
	private Composite client;
	private Text compositionName;
	private Button isActiveButton;
	private VagonMasterSectionPart allVagons;
	private VagonMasterSectionPart selectedVagons;
	private Button addVagonBtn;
	private Button removeVagonBtn;

	public CompositionDetailSectionPart(Composite parent, FormToolkit toolkit,
			int style, String sectionName) {
		super(parent, toolkit, style, sectionName);
	}

	@Override
	public CompositionSelection getSelection() {
		CompositionVO selectedComposition = selection.getSelectedComposition();
		if (selectedComposition == null) {
			selectedComposition = new CompositionVO();
		}
		selectedComposition.setActive(isActiveButton.getSelection());
		selectedComposition.setInternalId(compositionName.getText());
		Set<VagonVO> setVagons = new HashSet<VagonVO>();
		List<VagonVO> listVagons = selectedVagons.getSelection()
				.getListVagons();
		if (listVagons != null) {
			setVagons.addAll(listVagons);
		}
		selectedComposition.setSetVagons(setVagons);
		selection.setSelectedComposition(selectedComposition);
		return selection;
	}

	@Override
	public void setSelection(CompositionSelection selection) {
		this.selection = selection;
		logger.debug("Editor state: " + selection.getEditorState());
		switch (selection.getEditorState()) {
		case NEW:
			compositionName.setText("...");
			fillDualTable(true);
			client.setVisible(true);
			setEnabled(true);
			break;
		case CLEAN:
			fillEditorValues();
			setEnabled(false);
			break;
		case EDITING:
			fillEditorValues();
			setEnabled(true);
			break;
		}
	}

	private void fillEditorValues() {
		CompositionVO selectedComposition = selection.getSelectedComposition();
		if (selectedComposition != null) {
			compositionName.setText(selectedComposition.getInternalId());
			isActiveButton.setSelection(selectedComposition.isActive());
			fillDualTable(false);
			client.setVisible(true);
		} else {
			client.setVisible(false);
		}
	}

	private void fillDualTable(boolean isEnabled) {
		VagonSelection allVagonSelection = new VagonSelection();
		VagonSelection selectedVagonSelection = new VagonSelection();
		allVagonSelection.setEditorState(selection.getEditorState());
		allVagonSelection.setListVagons(selection.getListAllVagons());
		selectedVagonSelection.setEditorState(selection.getEditorState());
		if (selection.getSelectedComposition() != null) {
			selectedVagonSelection.setListVagons(new ArrayList<VagonVO>(
					selection.getSelectedComposition().getSetVagons()));
		}
		allVagons.setSelection(allVagonSelection);
		selectedVagons.setSelection(selectedVagonSelection);
		allVagons.setEnabled(true);
		selectedVagons.setEnabled(true);
	}

	@Override
	public void addSelectionListener(
			ISelectionListener<CompositionSelection> listner) {
	}

	@Override
	public void removeSelectionListener(
			ISelectionListener<CompositionSelection> listner) {
	}

	@Override
	protected void initGui(Section parentSection, FormToolkit toolkit) {
		logger.debug("Initializing GUI.");

		GridLayoutFactory.fillDefaults().numColumns(1).applyTo(parentSection);
		client = toolkit.createComposite(parentSection);
		GridLayoutFactory.fillDefaults().numColumns(2).margins(3, 3)
				.applyTo(client);
		parentSection.setClient(client);

		Label labelUserName = toolkit.createLabel(client,
				Messages.getString("compositions.master.label.name"));
		GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
				.grab(false, false).applyTo(labelUserName);
		compositionName = toolkit.createText(client, null);
		GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
				.grab(false, false).hint(120, SWT.DEFAULT)
				.applyTo(compositionName);

		isActiveButton = toolkit.createButton(client,
				Messages.getString("compositions.master.label.active"),
				SWT.CHECK);

		Composite dualTableComposite = toolkit.createComposite(client);
		GridLayoutFactory.fillDefaults().margins(3, 3).numColumns(3)
				.applyTo(dualTableComposite);
		GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL)
				.grab(true, true).span(2, 1).applyTo(dualTableComposite);

		Set<VagonMasterSectionPart.AvailableColumnsSL> setAllColumns = new HashSet<VagonMasterSectionPart.AvailableColumnsSL>();
		setAllColumns
				.add(VagonMasterSectionPart.AvailableColumnsSL.COLUMN_COMPOSITION_NAME);
		setAllColumns
				.add(VagonMasterSectionPart.AvailableColumnsSL.COLUMN_VAGON_NAME);
		allVagons = new VagonMasterSectionPart(
				dualTableComposite,
				toolkit,
				Section.TITLE_BAR,
				Messages.getString("compositions.master.label.dualtable.allvagons"),
				false, true, setAllColumns);
		GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.FILL)
				.grab(false, true).applyTo(allVagons.getSection());

		Composite buttonComposite = toolkit.createComposite(dualTableComposite);
		GridLayoutFactory.fillDefaults().margins(3, 3).numColumns(1)
				.applyTo(buttonComposite);
		GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
				.grab(true, true).applyTo(buttonComposite);

		addVagonBtn = toolkit.createButton(buttonComposite, "->", SWT.FLAT);
		GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL)
				.grab(false, false).applyTo(addVagonBtn);
		removeVagonBtn = toolkit.createButton(buttonComposite, "<-", SWT.FLAT);
		GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL)
				.grab(false, false).applyTo(removeVagonBtn);

		Set<VagonMasterSectionPart.AvailableColumnsSL> setSelectedColumns = new HashSet<VagonMasterSectionPart.AvailableColumnsSL>();
		setSelectedColumns
				.add(VagonMasterSectionPart.AvailableColumnsSL.COLUMN_VAGON_NAME);
		selectedVagons = new VagonMasterSectionPart(
				dualTableComposite,
				toolkit,
				Section.TITLE_BAR,
				Messages.getString("compositions.master.label.dualtable.selectedvagons"),
				false, true, setSelectedColumns);
		GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.FILL)
				.grab(false, true).applyTo(selectedVagons.getSection());

		toolkit.adapt(client);
		toolkit.paintBordersFor(client);
		client.setVisible(false);
	}

	@Override
	protected void postInitGui(Section parentSection, FormToolkit toolkit) {
	}

	@Override
	protected void initActions() {
		selectedVagons
				.addSelectionListener(new ISelectionListener<VagonSelection>() {

					@Override
					public void selectionChanged(VagonSelection selection) {
						logger.debug("Selection changed");
					}
				});
		allVagons
				.addSelectionListener(new ISelectionListener<VagonSelection>() {

					@Override
					public void selectionChanged(VagonSelection selection) {
						logger.debug("Selection changed");

					}
				});
		addVagonBtn.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				VagonSelection selectedVagonsSelection = selectedVagons
						.getSelection();
				VagonVO selectedVagon = allVagons.getSelection()
						.getSelectedVagon();
				allVagons.getSelection().getListVagons().remove(selectedVagon);
				if (selectedVagon == null) {
					return;
				}
				List<VagonVO> listSelectedVagons = selectedVagonsSelection
						.getListVagons();
				if (listSelectedVagons == null) {
					listSelectedVagons = new ArrayList<VagonVO>();
					selectedVagonsSelection.setListVagons(listSelectedVagons);
				}
				if (listSelectedVagons.contains(selectedVagon)) {
					return;
				}
				selectedVagon.setComposition(selection.getSelectedComposition());
				selectedVagonsSelection.getListVagons().add(selectedVagon);
				selectedVagons.setSelection(selectedVagonsSelection);
				allVagons.getSelection().getListVagons().add(selectedVagon);
				allVagons.setSelection(allVagons.getSelection());
				allVagons.setEnabled(true);
				selectedVagons.setEnabled(true);
			}
		});
		removeVagonBtn.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				VagonSelection selection = selectedVagons.getSelection();
				VagonVO selectedVagon = selection.getSelectedVagon();
				selectedVagon.setComposition(null);
				selection.getListVagons().remove(selectedVagon);
				selectedVagons.setSelection(selection);
				selectedVagons.setEnabled(true);
				allVagons.setEnabled(true);
			}
		});

	}

	@Override
	public void setEnabled(boolean isEnabled) {
		compositionName.setEnabled(isEnabled);
		isActiveButton.setEnabled(isEnabled);
		allVagons.setEnabled(isEnabled);
		selectedVagons.setEnabled(isEnabled);
		addVagonBtn.setEnabled(isEnabled);
		removeVagonBtn.setEnabled(isEnabled);
	}

}
